package cn.genmer.test.security.leetcode.easy;

import java.util.ArrayList;

/**
 *  507. 完美数(简单)
 *  对于一个 正整数，如果它和除了它自身以外的所有 正因子(约数- 可以除了不为0的) 之和相等，我们称它为 「完美数」。
 *
 * 给定一个 整数 n， 如果是完美数，返回 true，否则返回 false
 *
 *  
 *
 * 示例 1：
 *
 * 输入：num = 28
 * 输出：true
 * 解释：28 = 1 + 2 + 4 + 7 + 14
 * 1, 2, 4, 7, 和 14 是 28 的所有正因子。
 * 示例 2：
 *
 * 输入：num = 6
 * 输出：true
 * 示例 3：
 *
 * 输入：num = 496
 * 输出：true
 * 示例 4：
 *
 * 输入：num = 8128
 * 输出：true
 * 示例 5：
 *
 * 输入：num = 2
 * 输出：false
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/perfect-number
 */
public class PerfectNumber {
    public static void main(String[] args) {
        System.out.println(checkPerfectNumber3(28));
    }

    /**
     * 自己写的,枚举
     *
     * 	8 ms  42.53%	35.5 MB
     * @param num
     * @return
     */
    public static boolean checkPerfectNumber(int num) {
        if (num <=1) return false;
        ArrayList<Integer> nums = new ArrayList<>();
        nums.add(1);
        // 直接遍历2- 根号num的位置
        for (int i=2; i<= Math.sqrt(num)+1; i++){
            if (num % i == 0 && !nums.contains(i)) {
                nums.add(i);
                if (i * i != num) nums.add(num / i) ;
            }
        }
        return num == nums.stream().reduce(Integer::sum).orElse(0);
    }

    /**
     * 三叶 执行用时：
     * 1 ms 92.45%
     * 内存消耗：
     * 35.1 MB  64.31%
     * @param num
     * @return
     */
    public static boolean checkPerfectNumber2(int num) {
        if (num == 1) return false;
        int ans = 1;
        for (int i = 2; i <= num / i; i++) {
            if (num % i == 0) {
                ans += i;
                if (i * i != num) ans += num / i;
            }
        }
        return ans == num;
    }

    /**
     * 自己写的,枚举
     *
     * 	8 ms  42.53%	35.5 MB
     * @param num
     * @return
     */
    public static boolean checkPerfectNumber3(int num) {
        if (num <=1) return false;
        int result = 1;
        // 直接遍历2- 根号num的位置
        for (int i=2; i<= Math.sqrt(num)+1; i++){
            if (num % i == 0 && i > num /i) {
                result += i;
                if (i * i != num) result += num / i ;
            }
        }
        return num == result;
    }

}
